package com.itlong.cloud.controller.user;

import com.itlong.cloud.POJO.DTO.operate.OperateUserRecordPageDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyProjectGetBuildSimpleInfoDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyProjectGetUnitSimpleInfoDTO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.operate.OperateDeviceOpenTypeVO;
import com.itlong.cloud.POJO.VO.operate.OperateProjectInfoVO;
import com.itlong.cloud.POJO.VO.operate.OperateUserRecordVO;
import com.itlong.cloud.POJO.VO.property.PropertyProjectBuildSimpleInfoVO;
import com.itlong.cloud.POJO.VO.property.PropertyProjectUnitSimpleInfoVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.AuthAccessRequired;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.FileCatalogEnum;
import com.itlong.cloud.enumerate.OpenTypeEnum;
import com.itlong.cloud.enumerate.PropertyEquipTypeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.OperateErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.PropertyErrorCodeEnum;
import com.itlong.cloud.project.operate.IOperateProjectServiceClient;
import com.itlong.cloud.project.property.IPropertyBuildInfoServiceClient;
import com.itlong.cloud.project.property.IPropertyUnitInfoServiceClient;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.operate.IOperateUserRecordServiceClient;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.itlong.cloud.enumerate.PropertyEquipTypeEnum.UNKOWNTYPE;

/**
 * <desc>
 *      运营—APP用户模块—用户管理。
 * <desc/>
 *
 * @createDate 2017/10/19.
 */
@RestController
@RequestMapping("/appUser/record")
@RefreshScope
public class OperateUserRecordController  extends BaseController {

    private static final Logger LOG = LoggerFactory.getLogger(OperateUserRecordController.class);

    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;

    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;

    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;

    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;

    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    //业主通行记录
    @Autowired
    IOperateUserRecordServiceClient iOperateUserRecordServiceClient;

    //楼栋信息服务接口协议提供对象.
    @Autowired
    IPropertyBuildInfoServiceClient iPropertyBuildInfoServiceClient;

    //单元信息服务接口协议提供对象.
    @Autowired
    IPropertyUnitInfoServiceClient iPropertyUnitInfoServiceClient;

    //获取项目列表信息
    @Autowired
    IOperateProjectServiceClient iOperateProjectServiceClient;

    @Autowired
    RedisService redisService;

    /**
     * <desc>
     *      获取业主通行记录分页信息。通行记录有：门禁、电梯、云对讲
     * <desc/>
     *
     * @param  pageDTO 请求参数
     * @return 返回业主通行记录一页的记录信息
     * @author shengen.T
     * @createDate 2017/9/26
     */
    @AuthAccessRequired
    @RequestMapping(path="/getUserRecordPage",method = RequestMethod.POST)
    @ResponseBody
    public Object getUserRecordPage(OperateUserRecordPageDTO pageDTO) {
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            pageDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateUserRecordPageDTO.class,request);
            if(null==pageDTO || pageDTO.getRecTimeType()==null){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //判断通行记录类型
            Integer recType = pageDTO.getRecType();
            if((recType==null) || (PropertyEquipTypeEnum.getByEquipType(recType)==UNKOWNTYPE)) {
                return  new MessageVO(OperateErrorCodeEnum.RECORDTYPE_EMPTY_ERR.getErrorCode());
            }
            Page<OperateUserRecordVO> page= iOperateUserRecordServiceClient.getUserRecordPage(pageDTO);
            return  new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),page);
        } catch (Exception e) {
            throw new DataAccessException("【运营_用户_业主通行记录】获取分页列表失败",e);
        }
    }

    /**
     * <desc>
     * 分页查询指定项目下的楼栋简单信息（楼栋id ,楼栋名称）列表
     * </desc>
     *
     * @param projectId 查询楼栋简单信息（楼栋ID，楼栋名称）数据传输对象
     * @return 楼栋简单信息（楼栋id ,楼栋名称）列表
     * @author shengen.T
     * @createDate  2017/9/26
     */
    @RequestMapping(path = "/getBuildInfoLIst", method = RequestMethod.POST)
    @ResponseBody
    public Object getBuildInfoLIst( String projectId) {

          PropertyProjectGetBuildSimpleInfoDTO searchDTO  = new PropertyProjectGetBuildSimpleInfoDTO();
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId=request.getAttribute("projectId")==null?null:request.getAttribute("projectId").toString();

            //判断项目ID
            if(StringUtils.isEmpty(projectId)){
                return new MessageVO(OperateErrorCodeEnum.PUB_PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            searchDTO.setProjectId(projectId);
            searchDTO.setPageSize("1000");
            //分页查询楼栋简单信息列表
            Page<PropertyProjectBuildSimpleInfoVO> page = iPropertyBuildInfoServiceClient.getPageBuildSimpleInfoList(searchDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), page);
        } catch (Exception e) {
            throw new DataAccessException("【运营_业主通行记录_分页查询楼栋简单信息列表】", e);
        }
    }


    /**
     * <desc>
     * 分页查询指定楼栋下的单元简单信息（单元id ,单元名称）列表
     * </desc>
     *
     * @param buildId 查询单元简单信息（单元ID，单元名称）数据传输对象
     * @return MessageVO 标准格式化响应结果（含单元简单信息（单元id ,单元名称）列表）
     * @author shengen.T
     * @createDate  2017/9/26
     */
    @RequestMapping(path = "/getUnitInfoList", method = RequestMethod.POST)
    @ResponseBody
    public Object getUnitInfoList(String buildId) {
        PropertyProjectGetUnitSimpleInfoDTO searchDTO =  new PropertyProjectGetUnitSimpleInfoDTO();
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            buildId=request.getAttribute("buildId")==null?null:request.getAttribute("buildId").toString();
            //判断楼栋ID
            if(StringUtils.isEmpty(buildId)){
                return new MessageVO(OperateErrorCodeEnum.BUILD_ID_EMPTY_ERR.getErrorCode());
            }
            searchDTO.setBuildId(buildId);
            searchDTO.setPageSize("9000");
            //分页查询单元简单信息列表
            Page<PropertyProjectUnitSimpleInfoVO> page = iPropertyUnitInfoServiceClient.getPageUnitSimpleInfoList(searchDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), page);
        } catch (Exception e) {
            throw new DataAccessException("【运营_业主通行记录_分页查询单元简单信息列表】", e);
        }
    }

     /**
      * <desc>
      *      获取通行方式列表。
      * <desc/>
      *
      * @param recType
      * @return  返回通行方式列表 （通行方式Id 和通行方式名称）
      * @author shengen.T
      * @createDate 2017/10/31
      */
    @RequestMapping(path = "/getOpenTypeList", method = RequestMethod.POST)
    @ResponseBody
    public Object getOpenTypeList(Integer recType){
       try {
           HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
           try{
               recType=request.getAttribute("recType")==null?null : Integer.valueOf(request.getAttribute("recType").toString() );
           }catch (Exception e){
               return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
           }

           if((recType==null) || (PropertyEquipTypeEnum.getByEquipType(recType)==UNKOWNTYPE)) {
               return  new MessageVO(OperateErrorCodeEnum.RECORDTYPE_EMPTY_ERR.getErrorCode());
           }
           List<OperateDeviceOpenTypeVO>  openTyleList = iOperateUserRecordServiceClient.getOpenTypeList(recType);
           return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), openTyleList);
       }catch (Exception e){
           throw new DataAccessException("【运营_业主通行记录_获取通行方式列表】", e);
       }
    }
    
     /**
      * <desc>
      *      获取项目列表。
      * <desc/>
      *
      * @param  projectName 项目名称
      * @return 
      * @author shengen.T
      * @createDate 2018-01-12
      */
    @RequestMapping(path = "/getProjectInfoList", method = RequestMethod.POST)
    @ResponseBody
    public Object getProjectInfoList(String projectName){
        MessageVO messageVO;
        try{
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectName=request.getAttribute("projectName")==null?null:request.getAttribute("projectName").toString();
            if(StringUtils.isBlank(projectName)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<OperateProjectInfoVO> projectInfoVOS = iOperateProjectServiceClient.getProjectInfoList(projectName);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), projectInfoVOS);
        }catch (Exception e){
            throw new DataAccessException("【运营_通行记录_获取项目列表】", e);
        }
    }

    /**
     * <desc>
     *      导出通行记录
     * </desc>
     *
     * @param pageDTO 参数实体
     * @param request
     * @return
     * @Author Zhu.yj
     * @createDate  2020/3/27
     */
    @ResponseBody
    @AuthAccessRequired
    @RequestMapping(value = "/export",method = RequestMethod.POST)
    public Object export(OperateUserRecordPageDTO pageDTO, HttpServletRequest request){
        try{
            pageDTO = HttpProtocolUtil.parseRequestParamToDTO(OperateUserRecordPageDTO.class,request);
            if(null==pageDTO){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //判断通行记录类型
            Integer recType = pageDTO.getRecType();
            if((recType==null) || (PropertyEquipTypeEnum.getByEquipType(recType)==UNKOWNTYPE)) {
                return  new MessageVO(OperateErrorCodeEnum.RECORDTYPE_EMPTY_ERR.getErrorCode());
            }
            Page<OperateUserRecordVO> page= iOperateUserRecordServiceClient.getUserRecordPage(pageDTO);
            List<OperateUserRecordVO> operateUserRecordVOS = page.getRows();
            if (operateUserRecordVOS.size() == 0 || operateUserRecordVOS == null){
                return new MessageVO(OperateErrorCodeEnum.EXPORT_DATA_EMPTY_ERR.getErrorCode());
            }
            //定义表头
            String[] title = new String[]{"序号","所在项目","住户","设备名称","通行方式","通行时间"};
            //行高
            short rowHeight= 420;
            //创建excel工作簿
            HSSFWorkbook workbook=new HSSFWorkbook();
            //创建工作表sheet并设置简单格式
            HSSFSheet sheet=workbook.createSheet();
            sheet.setDefaultColumnWidth(20);
            //创建第一行
            HSSFRow row=sheet.createRow(0);
            row.setHeight(rowHeight);
            HSSFCell cell=null;
            //插入第一行数据的表头
            for (int i = 0; i < title.length; i++) {
                cell = row.createCell(i);
                cell.setCellValue(title[i]);
            }
            for (int recordIndex = 0;recordIndex<operateUserRecordVOS.size();recordIndex++){
                OperateUserRecordVO operateUserRecordVO = operateUserRecordVOS.get(recordIndex);
                int rowIndex = recordIndex+1;
                HSSFRow dataRow = sheet.createRow(rowIndex);
                dataRow.setHeight(rowHeight);
                HSSFCell noteCell = dataRow.createCell(0);
                noteCell.setCellValue(rowIndex);
                noteCell = dataRow.createCell(1);
                noteCell.setCellValue(operateUserRecordVO.getProjectInfo());
                noteCell = dataRow.createCell(2);
                noteCell.setCellValue(operateUserRecordVO.getUserInfo());
                noteCell = dataRow.createCell(3);
                noteCell.setCellValue(operateUserRecordVO.getDeviceName());
                noteCell = dataRow.createCell(4);
                noteCell.setCellValue(OpenTypeEnum.getByOpenType(operateUserRecordVO.getOpenType()).getDescription());
                noteCell = dataRow.createCell(5);
                noteCell.setCellValue(operateUserRecordVO.getPassTime());
                double percent = (recordIndex+1)/(double)operateUserRecordVOS.size();
                redisService.set(RedisConstant.OPERATE_USER_PASS_RECORD_CACHE_KEY+pageDTO.getLoginUserId(),RedisConstant.OPERATE_USER_PASS_RECORD_CACHE_TIME,percent);

            }
            String fileName = String.format("UserRecordInfo_%s.xls",
                    DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS"));
            fileName = URLEncoder.encode(fileName, "UTF-8");
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            workbook.write(os);
            byte[] content = os.toByteArray();
            InputStream exportFileStream = new ByteArrayInputStream(content);
            String exportfileUrl = uploadFile(exportFileStream,fileName);
            if (StringUtils.isBlank(exportfileUrl)){
                return new MessageVO(PropertyErrorCodeEnum.PROJECT_EXPORT_FILE_SAVE_ERR.getErrorCode());
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),(Object) exportfileUrl);

        }catch (Exception e){
            throw new DataAccessException("【运营_通行记录_导出用户通行记录export】导出用户通行记录失败",e);
        }
    }

    /**
     * <desc>
     *      获取导出数据百分比
     * </desc>
     *
     * @param
     * @return
     * @Author Zhu.yj
     * @createDate  2020/3/27
     */
    @ResponseBody
    @RequestMapping(value = "/getExportPercent",method = RequestMethod.POST)
    public Object getExportPercent(String loginUserId,HttpServletRequest request){
        try {
            loginUserId = request.getAttribute("loginUserId") == null ?null : request.getAttribute("loginUserId").toString();
            String percent = redisService.get(RedisConstant.OPERATE_USER_PASS_RECORD_CACHE_KEY+loginUserId);
            //当导出100%时，清除缓存
            if (("1.0").equals(percent)){
                redisService.del(RedisConstant.OPERATE_USER_PASS_RECORD_CACHE_KEY+loginUserId);
            }else if (percent == null){//清除缓存之后继续显示percent
                percent = "1.0";
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),(Object) percent);
        }catch(Exception e){
           throw new DataAccessException("【运营_通行记录_获取导出数据百分比getExportPercent】获取导出数据百分比失败",e);
        }
    }

    /**
     * <desc>
     *      Ftp上传文件，返回Url.
     * </desc>
     *
     * @param inputStream 文件流
     * @param fileName 文件名称
     * @return 文件上传成功后会返回Url,否则返回空
     * @author wangzhi
     * @createDate 2018/08/16
     */
    private String uploadFile(InputStream inputStream, String fileName) throws IOException {
        String fileUrl = "";
        String fileType = StringHandlerUtil.copySubStr(fileName, fileName.lastIndexOf('.') + 1, fileName.length());
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                inputStream,
                fileType,
                FILE_ACCESS_URL,
                FileCatalogEnum.USER_PASS_RECORD_UPLOAD_FILE.getType()
        );
        Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
        Boolean returnCode = (Boolean)resultMap.get("returnCode");
        if (returnCode == false){
            return fileUrl;
        }
        fileUrl = resultMap.get("accessPath").toString();
        return fileUrl;
    }
}

